package com.zgm.ch05.aop.pointcutAdvisor.composable._4_2;

import java.lang.reflect.Method;

import org.springframework.aop.Advisor;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.ComposablePointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.StaticMethodMatcher;

import com.zgm.ch05.aop.pointcutAdvisor.controlFlow._4_1_10.SimpleBeforeAdvice;

public class ComposablePointDemo {

	public static void main(String[] args) {
		SampleBean target = new SampleBean();
		
		ComposablePointcut pc = new ComposablePointcut(ClassFilter.TRUE, new GetterMethodMatcher());
		
		System.out.println("测试1 ：");
		SampleBean proxy = (SampleBean) getPrxoy(pc, target);
		testInvoke(proxy);
		
		System.out.println("测试2 ：");
		pc.union(new SetterMethodMatcher());
		proxy = getPrxoy(pc, target);
		testInvoke(proxy);
		
		System.out.println("测试3 ：");
		pc.intersection(new GetAgeMethodMatcher());
		proxy = getPrxoy(pc, target);
		testInvoke(proxy);
	}
	
	private static void testInvoke(SampleBean proxy) {
		proxy.getAge();
		proxy.getName();
		proxy.setName("zh");
	}
	public static SampleBean getPrxoy(ComposablePointcut pc, SampleBean target) {
		Advisor advisor = new DefaultPointcutAdvisor(pc, new SimpleBeforeAdvice());
		ProxyFactory pf = new ProxyFactory();
		pf.setTarget(target);
		pf.addAdvisor(advisor);
		
		return (SampleBean) pf.getProxy();
	}
	
	private static class GetterMethodMatcher extends StaticMethodMatcher {
		public boolean matches(Method method, Class targetClass) {
			return (method.getName().startsWith("get"));
		}

	}
	
	private static class GetAgeMethodMatcher extends StaticMethodMatcher {
		public boolean matches(Method method, Class targetClass) {
			return ("getAge".equals(method.getName()));
		}

	}
	
	private static class SetterMethodMatcher extends StaticMethodMatcher {
		public boolean matches(Method method, Class targetClass) {
			return (method.getName().startsWith("set"));
		}

	}
	
}
